#ifndef __REGEXP__

#define __REGEXP__

#include<string>
#include"nfa.h"

class NFA;

using std::string;

class NTRegExp;

class RegExp {	
	public:
	
	RegExp();
	RegExp(RegExp const &);
	virtual ~RegExp();
	
	virtual bool match(string const &) const = 0;
	virtual string toString() const = 0;
	virtual NFA toNFA() const = 0;
	virtual RegExp * copy() const = 0;
	//virtual RegExp * subst(std::map<unsigned, RegExp *> const &) const = 0;
	//virtual NTRegExp const * locateNT() const = 0;
};

class EmptyRegExp : public RegExp {
	public:
		
	EmptyRegExp();
	EmptyRegExp(EmptyRegExp const &);
	~EmptyRegExp();
	
	bool match(string const &) const;
	string toString() const;
	NFA toNFA() const;
	RegExp * copy() const;
	//RegExp * subst(std::map<unsigned, RegExp *> const &) const;
	//NTRegExp const * locateNT() const;
};

class LiteralRegExp : public RegExp {
	string contents;
	
	public:
		
	LiteralRegExp(string const &);
	LiteralRegExp(LiteralRegExp const &);
	~LiteralRegExp();
	
	bool match(string const &) const;
	string toString() const;
	NFA toNFA() const;
	RegExp * copy() const;
	//RegExp * subst(std::map<unsigned, RegExp *> const &) const;
	//NTRegExp const * locateNT() const;
};

class AlterRegExp : public RegExp {
	
	RegExp * left;
	RegExp * right;
	
	public:
		
	AlterRegExp(RegExp *, RegExp *);
	AlterRegExp(AlterRegExp const &);
	~AlterRegExp();
	
	bool match(string const &) const;
	string toString() const;
	NFA toNFA() const;
	RegExp * copy() const;
	//RegExp * subst(std::map<unsigned, RegExp *> const &) const;
	//NTRegExp const * locateNT() const;
};

class KleeneRegExp : public RegExp {
	RegExp * contents;
	
	public:
	KleeneRegExp(RegExp *);
	KleeneRegExp(KleeneRegExp const &);
	~KleeneRegExp();
	
	bool match(string const &) const;
	string toString() const;
	NFA toNFA() const;
	RegExp * copy() const;
	//RegExp * subst(std::map<unsigned, RegExp *> const &) const;
	//NTRegExp const * locateNT() const;
};

class ConcatRegExp : public RegExp {
	RegExp * left;
	RegExp * right;
	
	public:
		
	ConcatRegExp(RegExp *, RegExp *);
	ConcatRegExp(ConcatRegExp const &);
	~ConcatRegExp();
	
	bool match(string const &) const;
	string toString() const;
	NFA toNFA() const;
	RegExp * copy() const;
	//RegExp * subst(std::map<unsigned, RegExp *> const &) const;
	//NTRegExp const * locateNT() const;
};

/*class NTRegExp : public RegExp {
	
	public:
	
	unsigned contents;	
	
	NTRegExp(unsigned);
	NTRegExp(NTRegExp const &);
	~NTRegExp();
	
	bool match(string const &) const;
	string toString() const;
	NFA toNFA() const;
	RegExp * copy() const;
	RegExp * subst(std::map<unsigned, RegExp *> const &) const;
	NTRegExp const * locateNT() const;	
};*/

#endif
